package com.thwj.project.app.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult;
import com.thwj.project.app.event.PaySuccessEvent;
import com.thwj.project.biz.service.IActivityService;
import com.thwj.project.biz.service.IActivitySignupService;
import com.thwj.project.biz.service.IUserVipService;
import com.thwj.project.pay.domain.WxCallbackInfo;
import com.thwj.project.pay.domain.WxPay;
import com.thwj.project.pay.domain.WxRefundCallbackInfo;
import com.thwj.project.pay.enums.PayStatusEnum;
import com.thwj.project.pay.service.IWxCallbackInfoService;
import com.thwj.project.pay.service.IWxPayService;
import com.thwj.project.pay.service.IWxRefundCallbackInfoService;
import com.thwj.project.pay.service.IWxRefundInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;

@Slf4j
@Transactional
@Service
public class WxCallbackService {

    @Autowired
    IActivitySignupService activitySignupService;
    @Autowired
    IUserVipService userVipService;
    @Autowired
    IWxCallbackInfoService wxCallbackInfoService;
    @Autowired
    IWxRefundInfoService wxRefundInfoService;
    @Autowired
    IWxRefundCallbackInfoService wxRefundCallbackInfoService;
    @Autowired
    IWxPayService wxPayService;
    @Autowired
    IActivityService activityService;
    @Autowired
    AppAccountService appAccountService;
    @Autowired
    ApplicationEventPublisher applicationEventPublisher;


    public void paySuccessTradeOrder(WxPayOrderNotifyResult notifyResult) {

        //保存回调结果
        WxCallbackInfo callbackInfoDO = new WxCallbackInfo();
        callbackInfoDO.setBackData(notifyResult.toString());
        callbackInfoDO.setBackTime(new Date());
        callbackInfoDO.setAppid(notifyResult.getAppid());
        callbackInfoDO.setMuchId(notifyResult.getMchId());
        callbackInfoDO.setNonceStr(notifyResult.getNonceStr());
        callbackInfoDO.setSign(notifyResult.getSign());
        callbackInfoDO.setResultCode(notifyResult.getResultCode());
        callbackInfoDO.setOpenid(notifyResult.getOpenid());
        callbackInfoDO.setIsSubscribe(notifyResult.getIsSubscribe());
        callbackInfoDO.setTradeType(notifyResult.getTradeType());
        callbackInfoDO.setBankType(notifyResult.getBankType());
        callbackInfoDO.setTotalFee(notifyResult.getTotalFee());
        callbackInfoDO.setCashFee(notifyResult.getCashFee());
        callbackInfoDO.setTransactionId(notifyResult.getTransactionId());
        callbackInfoDO.setOutTradeNo(notifyResult.getOutTradeNo());
        callbackInfoDO.setTimeEnd(notifyResult.getTimeEnd());
        callbackInfoDO.setAttach(notifyResult.getAttach());
        callbackInfoDO.setReturnCode(notifyResult.getReturnCode());
        callbackInfoDO.setReturnMsg(notifyResult.getReturnMsg());
        callbackInfoDO.setErrCode(notifyResult.getErrCode());
        callbackInfoDO.setErrCodeDes(notifyResult.getErrCodeDes());
        callbackInfoDO.setDeviceInfo(notifyResult.getDeviceInfo());
        wxCallbackInfoService.save(callbackInfoDO);
        //微信支付回调，回调通知支付单状态变更
        if (callbackInfoDO.getReturnCode().equalsIgnoreCase("SUCCESS")
                && callbackInfoDO.getResultCode().equalsIgnoreCase("SUCCESS")) {
            // 1：读取更新订单支付表
            WxPay wxPay = wxPayService.getOne(new QueryWrapper<WxPay>().eq("order_number", callbackInfoDO.getOutTradeNo()),false);
            if(wxPay == null) {
                log.error("微信支付回调记录没有找到支付单数据 notifyResult:{}",notifyResult);
                return;
            }
            // 订单发现已支付 无需重复处理
            if(PayStatusEnum.PAID.getValue().intValue() == wxPay.getStatus()) {
                log.error("微信支付回调记录重复，无需再次梳理 notifyResult:{}, WxPay:{}", notifyResult, wxPay);
                return;
            }
            // 判断回调金额和我们下单的金额是否一致
            if(callbackInfoDO.getTotalFee().compareTo(wxPay.getActualMoney().multiply(new BigDecimal(100)).intValue()) != 0) {
                log.error("微信支付回调 金额不一致 notifyResult:{}, WxPay:{}", notifyResult, wxPay);
                return;
            }
            applicationEventPublisher.publishEvent(PaySuccessEvent.builder().callbackWxPay(wxPay).build());
        }

    }

    public void weChatRefundCallBackNotify(WxPayRefundNotifyResult result) {

        WxRefundCallbackInfo callbackInfoDO = new WxRefundCallbackInfo();
        callbackInfoDO.setBackDataBefore(result.getReqInfoString());
        callbackInfoDO.setBackDataAfter(result.getReqInfo().toString());
        callbackInfoDO.setBackTime(new Date());
        callbackInfoDO.setAppid(result.getAppid());
        callbackInfoDO.setMuchId(result.getMchId());
        callbackInfoDO.setNonceStr(result.getNonceStr());
        callbackInfoDO.setTotalFee(result.getReqInfo().getTotalFee());
        callbackInfoDO.setTransactionId(result.getReqInfo().getTransactionId());
        callbackInfoDO.setOutTradeNo(result.getReqInfo().getOutTradeNo());
        callbackInfoDO.setReturnCode(result.getReturnCode());
        callbackInfoDO.setReturnMsg(result.getReturnMsg());
        callbackInfoDO.setOutTradeNo(result.getReqInfo().getOutTradeNo());
        callbackInfoDO.setOutRefundNo(result.getReqInfo().getOutRefundNo());
        callbackInfoDO.setRefundStatus(result.getReqInfo().getRefundStatus());
        callbackInfoDO.setSettlementTotalFee(result.getReqInfo().getSettlementTotalFee());
        callbackInfoDO.setRefundFee(result.getReqInfo().getRefundFee());
        callbackInfoDO.setSettlementRefundFee(result.getReqInfo().getSettlementRefundFee());
        callbackInfoDO.setRefundRecvAccout(result.getReqInfo().getRefundRecvAccout());
        callbackInfoDO.setRefundAccount(result.getReqInfo().getRefundAccount());
        callbackInfoDO.setRefundRequestSource(result.getReqInfo().getRefundRequestSource());
        wxRefundCallbackInfoService.save(callbackInfoDO);

    }
}
